use crate::key_manager::error::KeyManagerError;
use crate::key_manager::model::Encoding;
use attestation_common::log::info;
use base64::{engine::general_purpose, Engine as _};

/// extended decode type
#[derive(Debug, Clone, Copy)]
pub enum DecodeEncoding {
    // ... 原有其他编码类型
    Pem,
}

impl From<&str> for DecodeEncoding {
    fn from(s: &str) -> Self {
        match s.to_lowercase().as_str() {
            // ... 其他匹配项
            "pem" => DecodeEncoding::Pem,
            _ => DecodeEncoding::Pem, // The default PEM format
        }
    }
}

impl From<&Encoding> for DecodeEncoding {
    fn from(s: &Encoding) -> Self {
        match s.to_lowercase().as_str() {
            "pem" => DecodeEncoding::Pem,
            _ => panic!("Unsupported encoding type: {}", s.to_lowercase().as_str()),
        }
    }
}

/// PEM解码专用函数
fn decode_pem(pem_str: &str) -> Result<Vec<u8>, KeyManagerError> {
    let pem_str = pem_str.trim();
    // Check whether PEM head and tail tags are included
    if !pem_str.starts_with("-----BEGIN") || !pem_str.ends_with("-----END PRIVATE KEY-----") {
        return Err(KeyManagerError::new(
            "The PEM format is invalid: Missing head and tail tags".to_string(),
        ));
    }

    // Extract the Base64 coded part
    let base64_data: String = pem_str
        .trim()
        .lines() // split by line
        .filter(|line| !line.starts_with("-----")) // Filter out head and tail tags
        .collect(); // Combine to String
    // Decode Base64 to DER format
    let der_data = general_purpose::STANDARD
        .decode(&base64_data)
        .map_err(|e| KeyManagerError::new(format!("Base64 decode failure: {}", e)))?;

    Ok(der_data)
}

/**
 * Decode tool method
 */
pub fn decode_from_string(
    encoded_str: &str,
    encoding: impl Into<DecodeEncoding>,
) -> Result<Vec<u8>, KeyManagerError> {
    info!("decode_from_string started");
    let encoding = encoding.into();

    match encoding {
        // ... 其他编码处理
        DecodeEncoding::Pem => decode_pem(encoded_str),
    }
}


#[cfg(test)]
mod tests {
    use super::*;

    // 测试缺少BEGIN标签的情况
    #[test]
    fn test_missing_begin_tag() {
        let invalid_pem = "END PRIVATE KEY-----";
        let result = decode_pem(invalid_pem);
        assert!(matches!(result, Err(KeyManagerError { .. })));
    }

    // 测试缺少END标签的情况
    #[test]
    fn test_missing_end_tag() {
        let invalid_pem = "-----BEGIN PRIVATE KEY-----";
        let result = decode_pem(invalid_pem);
        assert!(matches!(result, Err(KeyManagerError { .. })));
    }

    // 测试无效的Base64内容
    #[test]
    fn test_invalid_base64_content() {
        let invalid_pem = r#"-----BEGIN PRIVATE KEY-----
%%InvalidBase64%%
-----END PRIVATE KEY-----"#;

        let result = decode_pem(invalid_pem);
        assert!(result.is_err());
    }

    // 测试默认编码类型处理
    #[test]
    fn test_default_encoding_fallback() {
        let valid_pem = r#"-----BEGIN PRIVATE KEY-----
U2FtcGxlIERhdGE=
-----END PRIVATE KEY-----"#;

        // 使用不支持的编码类型，应fallback到默认PEM
        let result = decode_from_string(valid_pem, "invalid_enc").unwrap();
        assert_eq!(result, general_purpose::STANDARD.decode("U2FtcGxlIERhdGE=").unwrap());
    }
}
